package com.shlh.saas.service.impl;

import com.shlh.saas.service.SmsService;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

/**
 * 腾讯云短信服务实现
 */
@Service
@Primary  // 标记为主要实现
@Slf4j
public class TencentSmsServiceImpl implements SmsService {

    @Value("${tencent.sms.secret-id:}")
    private String secretId;

    @Value("${tencent.sms.secret-key:}")
    private String secretKey;

    @Value("${tencent.sms.app-id:}")
    private String appId;

    @Value("${tencent.sms.sign-name:}")
    private String signName;

    @Value("${tencent.sms.template-id:}")
    private String templateId;
    
    // 使用Guava Cache存储验证码，5分钟过期
    private final Cache<String, String> verificationCodes = CacheBuilder.newBuilder()
            .expireAfterWrite(5, TimeUnit.MINUTES)
            .build();

    @Override
    public boolean sendVerificationCode(String phone, String code) {
        try {
            log.info("开始发送腾讯云短信验证码, 手机号: {}, 验证码: {}", phone, code);
            
            // 开发模式，直接存储验证码无需真实发送
            if (isDevelopmentMode()) {
                log.info("开发模式：模拟发送短信验证码成功，手机号: {}, 验证码: {}", phone, code);
                verificationCodes.put(phone, code);
                return true;
            }
            
            // 检查配置是否完整
            if (secretId.isEmpty() || secretKey.isEmpty() || appId.isEmpty() || 
                signName.isEmpty() || templateId.isEmpty()) {
                log.warn("腾讯云短信配置不完整，无法发送短信");
                // 存储验证码，以便开发测试
                verificationCodes.put(phone, code);
                return false;
            }
            
            // 实例化一个认证对象
            Credential cred = new Credential(secretId, secretKey);
            
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            // 设置代理
            httpProfile.setEndpoint("sms.tencentcloudapi.com");
            
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            
            // 实例化要请求产品的client对象，clientProfile是可选的
            SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
            
            // 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
            SendSmsRequest req = new SendSmsRequest();
            
            // 短信应用ID
            req.setSmsSdkAppId(appId);
            // 短信签名内容
            req.setSignName(signName);
            // 模板ID
            req.setTemplateId(templateId);
            
            /* 模板参数: 若无模板参数，则设置为空 */
            String[] templateParamSet = {code};
            req.setTemplateParamSet(templateParamSet);
            
            /* 下发手机号码，采用E.164标准，+[国家或地区码][手机号]
             * 例如+8613711112222， 其中前面有一个+号，86为国家码，13711112222为手机号
             */
            String[] phoneNumberSet = {"+86" + phone};
            req.setPhoneNumberSet(phoneNumberSet);
            
            // 通过client对象调用SendSms方法发起请求，返回response对象
            SendSmsResponse response = client.SendSms(req);
            
            log.info("腾讯云短信发送结果: {}", response);
            
            // 将验证码存储到缓存，用于后续验证
            verificationCodes.put(phone, code);
            
            return true;
        } catch (TencentCloudSDKException e) {
            log.error("腾讯云短信发送失败: {}", e.getMessage(), e);
            return false;
        }
    }
    
    // 判断是否为开发模式
    private boolean isDevelopmentMode() {
        try {
            String env = System.getProperty("spring.profiles.active");
            return env != null && (env.equals("dev") || env.equals("local") || env.equals("test"));
        } catch (Exception e) {
            return false;
        }
    }
    
    @Override
    public String getStoredCode(String phone) {
        return verificationCodes.getIfPresent(phone);
    }
    
    @Override
    public void removeCode(String phone) {
        verificationCodes.invalidate(phone);
    }
} 